package com.example.his.api;

import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.alibaba.druid.support.spring.stat.annotation.Stat;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import javax.imageio.ImageIO;
import javax.print.DocFlavor;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 生成doxc文件的测试类
 **/
public class DemoReport {
  public static void main(String[] args) throws Exception {
    XWPFDocument doc = new XWPFDocument();
    //    设置文档的页边距
    CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
    CTPageMar pageMar = sectPr.addNewPgMar();
    pageMar.setLeft(BigInteger.valueOf(1200));
    pageMar.setRight(BigInteger.valueOf(1200));
    pageMar.setTop(BigInteger.valueOf(1000));
    pageMar.setBottom(BigInteger.valueOf(1000));
    
    //    设置页脚显示的页数
    XWPFFooter footer = doc.createFooter(HeaderFooterType.DEFAULT);
    XWPFParagraph paragraph = footer.createParagraph();
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    paragraph.getCTP().addNewFldSimple().setInstr("PAGE \\*MERGEFORMAT");
    
    //    创建参数对象
    HashMap param = new HashMap() {{
      put("uuid", "0121312313548465as5da5d465ad5");
      put("item", new ArrayList <>() {{
        add(new HashMap <>() {{
          put("label", "姓    名:");
          put("value", "张三");
        }});
        add(new HashMap <>() {{
          put("label", "性    别:");
          put("value", "男");
        }});
        add(new HashMap <>() {{
          put("label", "单    位:");
          put("value", "JAVA联盟");
        }});
        add(new HashMap <>() {{
          put("label", "日    期:");
          put("value", "2024/07/12");
        }});
      }});
      put("name", "张三");
      put("sex", "女");
      
      put("birthday", "1990/12/07");
      put("age", "33");
      put("tel", "13871999999");
      put("date", "2024/07/12");
      put("company", "xxx集团");
      put("goods", "某某体检套餐");
    }};
    
    //    生成封面页
    createCover(doc, param);
    
    // 渲染首页标题和欢迎词
    createWelcome(doc, param);
    
    //    生成体检人信息表格
    createCustomerInfo(doc, param);
    
    //    体检项目
    ArrayList list = new ArrayList() {{
      add(new HashMap <>() {{
        put("place", "眼科");
        put("item", "裸眼视力（左）");
      }});
      add(new HashMap <>() {{
        put("place", "眼科");
        put("item", "裸眼视力（有）");
      }});
      add(new HashMap <>() {{
        put("place", "眼科");
        put("item", "灯光检查");
      }});
      add(new HashMap <>() {{
        put("place", "一般科室");
        put("item", "身高");
      }});
      add(new HashMap <>() {{
        put("place", "一般科室");
        put("item", "体重");
      }});
      add(new HashMap <>() {{
        put("place", "采血室");
        put("item", "血常规");
      }});
      add(new HashMap <>() {{
        put("place", "采血室");
        put("item", "心电图");
      }});
    }};
    //    体检项目
    createCheckup(doc, list);
    
    
    HashMap checkupResult = new HashMap() {{
      put("place", "外科");
      put("doctor", "于医生");
      put("date", "2024-12-12");
      put("item", new ArrayList() {{
        add(new HashMap() {{
          put("name", "淋巴结");
          put("value", "未见一场");
          put("unit", null);
          put("standard", null);
        }});
        add(new HashMap() {{
          put("name", "甲状腺");
          put("value", "未见一场");
          put("unit", null);
          put("standard", null);
        }});
        add(new HashMap() {{
          put("name", "淋巴结");
          put("value", "未见一场");
          put("unit", null);
          put("standard", null);
        }});
      }});
    }};
    //  体检结果
    createCheckupResultBytemplate_1(doc, checkupResult);
    
    //    心电图
    HashMap map = new HashMap() {{
      put("place", "心电图室");
      put("doctor", "张瑞");
      put("date", "2024-12-15");
      put("image", "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage109.360doc.com%2FDownloadImg%2F2024%2F06%2F1115%2F284736939_5_20240611034556283.png&refer=http%3A%2F%2Fimage109.360doc.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1725728450&t=02cc793b1f0d94e4d77ccfcd101cca94");
      put("item", new ArrayList() {{
        add(new HashMap <>() {{
          put("name", "心电图");
          put("value", "【pbo】,【超声波】,avr倒置,无异常,");
          put("unit", null);
          put("standard", null);
        }});
      }});
    }};
    
    //  体检结果 心电图
    createCheckupResultBytemplate_2(doc, map);
    
    try(FileOutputStream out = new FileOutputStream("F:\\test." +
        "");) {
      doc.write(out);
      System.out.println("生成成功");
    } catch(IOException e) {
      e.printStackTrace();
      //      throw new RuntimeException(e);
    }
  }
  
  private static void createCheckupResultBytemplate_2(XWPFDocument doc, HashMap param) throws IOException, InvalidFormatException {
    String place = MapUtil.getStr(param, "place");
    String doctor = MapUtil.getStr(param, "doctor");
    String date = MapUtil.getStr(param, "date");
    List <Map> item = MapUtil.get(param, "item", List.class);
    String image = MapUtil.getStr(param, "image");
    
    XWPFParagraph paragraph = doc.createParagraph();
    paragraph.setBorderBottom(Borders.BABY_RATTLE);
    
    XWPFRun run = paragraph.createRun();
    run.setFontSize(14);
    run.setFontFamily("Microsoft Yahei");
    run.setTextHighlightColor("lightGray");
    run.setText("【" + place + "体检结果】");
    // 设置上下外填充
    CTSpacing ctSpacing = paragraph.getCTP().addNewPPr().addNewSpacing();
    ctSpacing.setBeforeLines(BigInteger.valueOf(250));
    ctSpacing.setAfterLines(BigInteger.valueOf(150));
    
    //    插入图片
    if(image != null) {
      URL url = new URL(image);
      InputStream in = url.openStream();
      BufferedImage bufferedImage = ImageIO.read(url);
      int width = bufferedImage.getWidth();
      int height = bufferedImage.getHeight();
      //      调整图片尺寸适配宽度
      double scaling = 1.0;
      if(width > 72 * 9.13) {
        scaling = (72.0 * 9.13) / width;
      }
      paragraph = doc.createParagraph();
      paragraph.setAlignment(ParagraphAlignment.LEFT);
      //      设置图片下外填充
      ctSpacing = paragraph.getCTP().addNewPPr().addNewSpacing();
      ctSpacing.setAfterLines(BigInteger.valueOf(150));
      
      //      往段落中插入图片
      run = paragraph.createRun();
      run.addPicture(in, XWPFDocument.PICTURE_TYPE_PNG, "image.png", Units.pixelToEMU((int)(width * scaling)), Units.toEMU((int)(height * scaling)));
    }
    
    /**
     * 插入表格
     * **/
    XWPFTable table = doc.createTable(item.size() + 1, 5);
    CTTblPr tblPr = table.getCTTbl().getTblPr();
    //    设置表格总宽度
    tblPr.getTblW().setType(STTblWidth.DXA);
    tblPr.getTblW().setW(BigInteger.valueOf(9850));
    
    //    设置表头
    XWPFTableRow row = table.getRow(0);
    row.setHeight(500);
    List <XWPFTableCell> tableCells = row.getTableCells();
    String[] array = { "序号#800", "检查项目#2200", "检查结果#3000", "单位#1200", "参考值#1300", };
    for(int i = 0; i <= 4; i++) {
      XWPFTableCell cell = tableCells.get(i);
      cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
      cell.setColor("F0F0F0");
      paragraph = cell.getParagraphArray(0);
      if(i != 2) {
        //        除第三列外的文字居中对齐
        paragraph.setAlignment(ParagraphAlignment.CENTER);
      } else {
        //        左对齐
        paragraph.setIndentationLeft(200);
      }
      run = paragraph.createRun();
      run.setFontSize(10);
      run.setFontFamily("Microsoft Yahei");
      
      //    设置表头文字
      String label = array[i].split("#")[0];
      //      表头列宽
      int width = Integer.parseInt(array[i].split("#")[1]);
      run.setText(label);
      //      表头列宽
      CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
      CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
      ctTblWidth.setW(BigInteger.valueOf(width));
    }
    
    //    设置体检结果
    for(int i = 0; i < item.size(); i++) {
      Map map = item.get(i);
      String name = MapUtil.getStr(map, "name");
      String value = MapUtil.getStr(map, "value");
      String unit = MapUtil.getStr(map, "unit");
      unit = unit == null ? "" : unit;
      String standard = MapUtil.getStr(map, "standard");
      standard = standard == null ? "" : standard;
      String[] temp = { i + 1 + "", name, value, unit, standard, };
      
      row = table.getRow(i + 1);
      row.setHeight(500);
      tableCells = row.getTableCells();
      for(int j = 0; j < temp.length; j++) {
        XWPFTableCell cell = tableCells.get(j);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        paragraph = cell.getParagraphArray(0);
        run = paragraph.createRun();
        run.setFontSize(10);
        run.setFontFamily("Microsoft Yahei");
        if(j != 2) {
          //   除第三列外的文字居中对齐
          paragraph.setAlignment(ParagraphAlignment.CENTER);
          run.setText(temp[j]);
        } else {
          //          左对齐
          paragraph.setAlignment(ParagraphAlignment.LEFT);
          paragraph.setIndentationLeft(200);
          String[] strs = temp[j].split("#");
          for(int k = 0; k < strs.length; k++) {
            String one = array[k];
            run.setText(one);
            if(k < array.length - 1) {
              run.addBreak(); // 换行
            }
          }
        }
        //        //      表头列宽
        int width = Integer.parseInt(array[j].split("#")[1]);
        CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
        CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
        ctTblWidth.setW(BigInteger.valueOf(width));
      }
    }
    //    设置体检医生和日期
    paragraph = doc.createParagraph();
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("体检医生：" + doctor + "\t\t\t\t\t\t\t\t\t\t日期：" + date);
    
    //    设置上下外填充
    CTPPr ctpPr = paragraph.getCTP().addNewPPr();
    ctSpacing = ctpPr.addNewSpacing();
    ctSpacing.setBeforeLines(BigInteger.valueOf(100));
    ctSpacing.setAfterLines(BigInteger.valueOf(150));
    
  }
  
  //  体检结果
  private static void createCheckupResultBytemplate_1(XWPFDocument doc, HashMap param) {
    String place = MapUtil.getStr(param, "place");
    String doctor = MapUtil.getStr(param, "doctor");
    String date = MapUtil.getStr(param, "date");
    List <Map> item = MapUtil.get(param, "item", List.class);
    
    XWPFParagraph paragraph = doc.createParagraph();
    //  设置段落下边框线
    paragraph.setBorderBottom(Borders.BABY_RATTLE);
    
    XWPFRun run = paragraph.createRun();
    run.setFontSize(14);
    run.setFontFamily("Microsoft Yahei");
    run.setTextHighlightColor("lightGray");
    run.setText("【" + place + "体检结果】");
    
    //    设置上下外填充
    CTPPr ctpPr = paragraph.getCTP().addNewPPr();
    CTSpacing ctSpacing = ctpPr.addNewSpacing();
    ctSpacing.setBeforeLines(BigInteger.valueOf(250));
    ctSpacing.setAfterLines(BigInteger.valueOf(150));
    
    /**
     * 插入表格
     * **/
    XWPFTable table = doc.createTable(item.size() + 1, 5);
    CTTblPr tblPr = table.getCTTbl().getTblPr();
    //    设置表格总宽度
    tblPr.getTblW().setType(STTblWidth.DXA);
    tblPr.getTblW().setW(BigInteger.valueOf(9850));
    
    //    设置表头
    XWPFTableRow row = table.getRow(0);
    row.setHeight(500);
    List <XWPFTableCell> tableCells = row.getTableCells();
    String[] array = { "序号#800", "检查项目#2200", "检查结果#3000", "单位#1200", "参考值#1300", };
    for(int i = 0; i < array.length; i++) {
      XWPFTableCell cell = tableCells.get(i);
      cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
      cell.setColor("F0F0F0");
      paragraph = cell.getParagraphArray(0);
      if(i != 2) {
        //        除第三列外的文字居中对齐
        paragraph.setAlignment(ParagraphAlignment.CENTER);
      } else {
        //        左对齐
        paragraph.setIndentationLeft(200);
      }
      run = paragraph.createRun();
      run.setFontSize(10);
      run.setFontFamily("Microsoft Yahei");
      
      //    设置表头文字
      String label = array[i].split("#")[0];
      //      表头列宽
      int width = Integer.parseInt(array[i].split("#")[1]);
      run.setText(label);
      //      表头列宽
      CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
      CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
      ctTblWidth.setW(BigInteger.valueOf(width));
    }
    
    //    设置体检结果
    for(int i = 0; i < item.size(); i++) {
      Map map = item.get(i);
      String name = MapUtil.getStr(map, "name");
      String value = MapUtil.getStr(map, "value");
      String unit = MapUtil.getStr(map, "unit");
      unit = unit == null ? "" : unit;
      String standard = MapUtil.getStr(map, "standard");
      standard = standard == null ? "" : standard;
      String[] temp = { i + 1 + "", name, value, unit, standard, };
      
      row = table.getRow(i + 1);
      row.setHeight(500);
      tableCells = row.getTableCells();
      for(int j = 0; j < temp.length; j++) {
        XWPFTableCell cell = tableCells.get(j);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        paragraph = cell.getParagraphArray(0);
        if(j != 2) {
          //   除第三列外的文字居中对齐
          paragraph.setAlignment(ParagraphAlignment.CENTER);
        } else {
          //          左对齐
          paragraph.setIndentationLeft(200);
        }
        run = paragraph.createRun();
        run.setFontSize(10);
        run.setFontFamily("Microsoft Yahei");
        run.setText(temp[j]);
        //        //      表头列宽
        int width = Integer.parseInt(array[j].split("#")[1]);
        CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
        CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
        ctTblWidth.setW(BigInteger.valueOf(width));
      }
    }
    
    //    设置体检医生和日期
    paragraph = doc.createParagraph();
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("体检医生：" + doctor + "\t\t\t\t\t\t\t\t\t\t日期：" + date);
    
    //    设置上下外填充
    ctpPr = paragraph.getCTP().addNewPPr();
    ctSpacing = ctpPr.addNewSpacing();
    ctSpacing.setBeforeLines(BigInteger.valueOf(100));
    ctSpacing.setAfterLines(BigInteger.valueOf(150));
    
    
  }
  
  
  //  渲染封面
  public static void createCover(XWPFDocument doc, HashMap param) throws Exception
  {
    //    创建顶部体检中心的中文名称
    XWPFParagraph paragraph = doc.createParagraph();
    XWPFRun run = paragraph.createRun();
    run.setBold(true); // 字体加粗
    run.setFontSize(20); // 字体大小
    run.setFontFamily("Microsoft Yahei"); // 雅黑字体
    run.setUnderline(UnderlinePatterns.THICK); // 下划线
    run.setText("xxx大健康体检中心");
    //   设置行间距
    CTP ctp = paragraph.getCTP();
    CTPPr ctpPr = ctp.addNewPPr();
    CTSpacing ctSpacing = ctpPr.addNewSpacing();
    ctSpacing.setLineRule(STLineSpacingRule.EXACT); // 固定行间距
    ctSpacing.setLine(BigInteger.valueOf(480));
    
    //   下划线下的英文名称
    paragraph = doc.createParagraph();
    run = paragraph.createRun();
    run.setFontSize(10); // 字体大小
    run.setFontFamily("Microsoft Yahei"); // 雅黑字体
    run.setText("xxx Health Check Center");
    //    设置行间距
    ctp = paragraph.getCTP();
    ctpPr = ctp.addNewPPr();
    ctSpacing = ctpPr.addNewSpacing();
    ctSpacing.setLineRule(STLineSpacingRule.EXACT);
    ctSpacing.setLine(BigInteger.valueOf(280));
    
    
    //    创建体检报告标题
    paragraph = doc.createParagraph();
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setBold(true);
    run.setFontSize(26);
    run.setFontFamily("Microsoft Yahei");
    run.setText("体检报告");
    //    设置段落之间的间距
    ctp = paragraph.getCTP();
    ctpPr = ctp.addNewPPr();
    ctSpacing = ctpPr.addNewSpacing();
    //    上下段落间距较大，腾出空白空间
    ctSpacing.setBeforeLines(BigInteger.valueOf(800));
    ctSpacing.setAfterLines(BigInteger.valueOf(800));
    
    
    //    插入体检二维码图片
    QrConfig qrConfig = new QrConfig();
    qrConfig.setWidth(150);
    qrConfig.setHeight(150);
    qrConfig.setMargin(2);
    String uuid = MapUtil.getStr(param, "uuid");
    BufferedImage bufferedImage = QrCodeUtil.generate(uuid, qrConfig);
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    //    将二维码图片对象的内容写道输出流中
    ImageIO.write(bufferedImage, "jpg", bout);
    //    用输入流获取输出流的内容
    InputStream input = new ByteArrayInputStream(bout.toByteArray());
    
    //    创建新的段落
    paragraph = doc.createParagraph();
    //     图片居中对齐
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    //    设置图片下外边填充
    ctp = paragraph.getCTP();
    ctpPr = ctp.addNewPPr();
    ctSpacing = ctpPr.addNewSpacing();
    ctSpacing.setAfterLines(BigInteger.valueOf(400));
    run = paragraph.createRun();
    //    往段落中插入图片
    XWPFPicture xwpfPicture = run.addPicture(input, Document.PICTURE_TYPE_JPEG, "", Units.pixelToEMU(bufferedImage.getWidth()), Units.pixelToEMU(bufferedImage.getHeight()));
    
    //    插入表格
    XWPFTable table = doc.createTable(4, 2);
    //    表格处于水平居中
    table.setTableAlignment(TableRowAlign.CENTER);
    table.getCTTbl().getTblPr().unsetTblBorders(); //    表格没有边框
    
    //    获取静态数据
    ArrayList list = (ArrayList)param.get("item");
    for(int i = 0; i < list.size(); i++) {
      HashMap map = (HashMap)list.get(i);
      String label = MapUtil.getStr(map, "label");
      String value = MapUtil.getStr(map, "value");
      XWPFTableRow row = table.getRow(i);
      row.setHeight(600);
      List <XWPFTableCell> tableCells = row.getTableCells();
      //      设置第二列宽度
      CTTcPr ctTcPr = tableCells.get(1).getCTTc().addNewTcPr();
      CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
      ctTblWidth.setW(BigInteger.valueOf(2800));
      
      
      //      设置当前行的第一个单元格内容
      paragraph = tableCells.get(0).getParagraphArray(0);
      paragraph.setAlignment(ParagraphAlignment.CENTER); //      居中对齐
      run = paragraph.createRun();
      run.setFontSize(10);
      run.setFontFamily("Microsoft Yahei"); // 雅黑字体
      run.setText(label + "  ");
      
      // 设置当前行的第二个单元格内容
      paragraph = tableCells.get(1).getParagraphArray(0);
      paragraph.setAlignment(ParagraphAlignment.CENTER); //      居中对齐
      //      设置段落下边框线
      //      paragraph.setBorderBottom(Borders.BABY_RATTLE);  //      细线
      run = paragraph.createRun();
      run.setFontFamily("Microsoft Yahei");
      run.setText("   " + value);
    }
    
  }
  
  //  渲染首页标题和欢迎词
  public static void createWelcome(XWPFDocument doc, HashMap param) {
    //    创建标题文字
    XWPFParagraph paragraph = doc.createParagraph();
    paragraph.setAlignment(ParagraphAlignment.CENTER); //      居中对齐
    XWPFRun run = paragraph.createRun();
    run.setFontFamily("Microsoft Yahei");
    run.setFontSize(18);
    run.setText("体检报告");
    
    CTP ctp = paragraph.getCTP();
    CTPPr ctpPr = ctp.addNewPPr();
    CTSpacing ctSpacing = ctpPr.addNewSpacing();
    //    设置行间距
    ctSpacing.setLineRule(STLineSpacingRule.EXACT); // 固定行间距
    ctSpacing.setLine(BigInteger.valueOf(420));
    //    设置上外填充，实现另起一页
    ctSpacing.setBeforeLines(BigInteger.valueOf(2000));
    //    设置下外填充
    ctSpacing.setAfterLines(BigInteger.valueOf(200));
    
    //    创建第一行文字
    run = doc.createParagraph().createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    String name = MapUtil.getStr(param, "name");
    String sex = MapUtil.getStr(param, "sex");
    String temp = name + (sex.equals("男") ? "先生" : "女士");
    run.setText("尊敬的" + temp + "，您好！");
    ctSpacing = paragraph.getCTP().addNewPPr().addNewSpacing();
    ctSpacing.setLineRule(STLineSpacingRule.EXACT);
    ctSpacing.setLine(BigInteger.valueOf(380));
    ctSpacing.setAfterLines(BigInteger.valueOf(50));
    
    //    创建第二行文字
    paragraph = doc.createParagraph();
    //    段首缩进两个汉字
    paragraph.setIndentationFirstLine(600);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("体检报告已生成，现将您的体检汇总结果如下，请认真阅读并妥善保管。现将您的体检汇总结果如下，请认真阅读并妥善保管。现将您的体检汇总结果如下，请认真阅读并妥善保管。现将您的体检汇总结果如下，请认真阅读并妥善保管。");
    ctSpacing = paragraph.getCTP().addNewPPr().addNewSpacing();
    ctSpacing.setLineRule(STLineSpacingRule.EXACT);
    ctSpacing.setLine(BigInteger.valueOf(380));
    ctSpacing.setAfterLines(BigInteger.valueOf(100));
    
  }
  
  
  //    生成体检人信息表格
  private static void createCustomerInfo(XWPFDocument doc, HashMap param) {
    XWPFParagraph paragraph = doc.createParagraph();
    XWPFRun run = paragraph.createRun();
    run.setFontSize(14);
    run.setFontFamily("Microsoft Yahei");
    run.setText("体检人信息");
    //    设置上下外填充
    CTSpacing ctSpacing = paragraph.getCTP().addNewPPr().addNewSpacing();
    ctSpacing.setBeforeLines(BigInteger.valueOf(200));
    ctSpacing.setAfterLines(BigInteger.valueOf(200));
    
    //    插入表格
    XWPFTable table = doc.createTable(4, 6);
    CTTblPr tblPr = table.getCTTbl().getTblPr();
    //    设置表格总宽度
    tblPr.getTblW().setType(STTblWidth.DXA);
    tblPr.getTblW().setW(BigInteger.valueOf(9850));
    
    //    第一行
    XWPFTableRow row = table.getRow(0);
    row.setHeight(550);
    List <XWPFTableCell> tableCells = row.getTableCells();
    
    //    设置姓名label
    XWPFTableCell cell = tableCells.get(0);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    cell.setColor("f0f0f0");
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("姓名");
    //    设置列宽
    CTTcPr ctTcPr = cell.getCTTc().addNewTcPr();
    CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    
    //    设置姓名value
    cell = tableCells.get(1);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText(MapUtil.getStr(param, "name"));
    
    //    设置性别  label
    cell = tableCells.get(2);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    cell.setColor("f0f0f0");
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("性别");
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    
    //    设置性别value‘
    cell = tableCells.get(3);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText(MapUtil.getStr(param, "sex"));
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    
    //    设置生日label‘
    cell = tableCells.get(4);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    cell.setColor("f0f0f0");
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("出生日期");
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    
    //    设置生日value
    cell = tableCells.get(5);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText(MapUtil.getStr(param, "birthday"));
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    
    //    第二行
    row = table.getRow(1);
    row.setHeight(550);
    tableCells = row.getTableCells();
    //    设置电话label
    cell = tableCells.get(0);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    cell.setColor("f0f0f0");
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(9);
    run.setFontFamily("Microsoft Yahei");
    run.setText("电话");
    //    设置电话的value
    cell = tableCells.get(1);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(9);
    run.setFontFamily("Microsoft Yahei");
    run.setText(MapUtil.getStr(param, "tel"));
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    
    //    设置年龄label
    cell = tableCells.get(2);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    cell.setColor("f0f0f0");
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(9);
    run.setFontFamily("Microsoft Yahei");
    run.setText("年龄");
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    //    设置年龄的value
    cell = tableCells.get(3);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(9);
    run.setFontFamily("Microsoft Yahei");
    run.setText(MapUtil.getStr(param, "age"));
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    
    //    设置体检日label
    cell = tableCells.get(4);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    cell.setColor("f0f0f0");
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(9);
    run.setFontFamily("Microsoft Yahei");
    run.setText("体检日期");
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    //    设置年龄的value
    cell = tableCells.get(5);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(9);
    run.setFontFamily("Microsoft Yahei");
    run.setText(MapUtil.getStr(param, "date"));
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    
    
    //    第三行
    row = table.getRow(2);
    row.setHeight(550);
    tableCells = row.getTableCells();
    //    设置工作单位label
    cell = tableCells.get(0);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    cell.setColor("f0f0f0");
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("单位名称");
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    //    设置工作单位的value
    cell = tableCells.get(1);
    cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.LEFT);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("    " + param.get("company"));
    //    给后面四个单元格设置stmerge。continue，让他们不显示，也就是当前单元格占5格
    for(int i = 2; i < 6; i++) {
      cell = tableCells.get(i);
      cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
    }
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(7500));
    
    //    第四行
    row = table.getRow(3);
    row.setHeight(600);
    tableCells = row.getTableCells();
    //    设置体检套餐label
    cell = tableCells.get(0);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    cell.setColor("f0f0f0");
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.CENTER);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("体检套餐");
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(1500));
    //    设置体检套餐的value
    cell = tableCells.get(1);
    cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    paragraph = cell.getParagraphArray(0);
    paragraph.setAlignment(ParagraphAlignment.LEFT);
    run = paragraph.createRun();
    run.setFontSize(10);
    run.setFontFamily("Microsoft Yahei");
    run.setText("    " + param.get("goods"));
    //    给后面四个单元格设置stmerge。continue，让他们不显示，也就是当前单元格占5格
    for(int i = 2; i < 6; i++) {
      cell = tableCells.get(i);
      cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
    }
    //    设置列宽
    ctTcPr = cell.getCTTc().addNewTcPr();
    ctTblWidth = ctTcPr.addNewTcW();
    ctTblWidth.setW(BigInteger.valueOf(7500));
    
    
  }
  
  //  体检项目
  private static void createCheckup(XWPFDocument doc, ArrayList list) {
    XWPFParagraph paragraph = doc.createParagraph();
    XWPFRun run = paragraph.createRun();
    run.setFontSize(14);
    run.setFontFamily("Microsoft Yahei");
    run.setText("体检内容");
    //    设置上下外填充
    CTSpacing ctSpacing = paragraph.getCTP().addNewPPr().addNewSpacing();
    ctSpacing.setBeforeLines(BigInteger.valueOf(200));
    ctSpacing.setAfterLines(BigInteger.valueOf(100));
    
    //    插入表格
    XWPFTable table = doc.createTable(list.size() + 1, 3);
    CTTblPr tblPr = table.getCTTbl().getTblPr();
    //    设置表格总宽度
    tblPr.getTblW().setType(STTblWidth.DXA);
    tblPr.getTblW().setW(BigInteger.valueOf(9850));
    //    表头文字
    String[] array = { "序号", "体检科室", "体检内容", };
    
    //    第一行 (表投行）
    XWPFTableRow row = table.getRow(0);
    row.setHeight(550);
    List <XWPFTableCell> tableCells = row.getTableCells();
    for(int i = 0; i < array.length; i++) {
      String text = array[i];
      //    设置姓名label
      XWPFTableCell cell = tableCells.get(i);
      cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
      cell.setColor("f0f0f0");
      paragraph = cell.getParagraphArray(0);
      paragraph.setAlignment(ParagraphAlignment.CENTER);
      run = paragraph.createRun();
      run.setFontSize(10);
      run.setFontFamily("Microsoft Yahei");
      run.setText(text);
    }
    
    //    生成表格其余行
    String temp = null;
    int index = 0;
    for(int i = 0; i < list.size(); i++) {
      Map one = (Map)list.get(i);
      String place = MapUtil.getStr(one, "place");
      String item = MapUtil.getStr(one, "item");
      row = table.getRow(i + 1);
      row.setHeight(550);
      tableCells = row.getTableCells();
      
      //      当前行的第二列（科室名称）
      XWPFTableCell cell = tableCells.get(1);
      STMerge.Enum val = null;
      //      判断当前体检日期的名称跟上脚尖项目的科室名称是否不相同
      if(! place.equals(temp)) {
        index++;
        temp = place;
        //        当前单元格正常显示
        val = STMerge.RESTART;
        cell.getCTTc().addNewTcPr().addNewVMerge().setVal(val);
      } else {
        //        的囊谦单元格不显示，让上一个单元格体现垂直合并的效果
        val = STMerge.CONTINUE;
        cell.getCTTc().addNewTcPr().addNewVMerge().setVal(val);
      }
      
      cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
      paragraph = cell.getParagraphArray(0);
      paragraph.setAlignment(ParagraphAlignment.CENTER);
      run = paragraph.createRun();
      run.setFontSize(10);
      run.setFontFamily("Microsoft Yahei");
      run.setText(place);
      
      //      第一列（序号）
      cell = tableCells.get(0);
      cell.getCTTc().addNewTcPr().addNewVMerge().setVal(val);
      cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
      paragraph = cell.getParagraphArray(0);
      paragraph.setAlignment(ParagraphAlignment.CENTER);
      run = paragraph.createRun();
      run.setFontSize(10);
      run.setFontFamily("Microsoft Yahei");
      run.setText(String.valueOf(index));
      
      //      第三列（体检项目名称）
      cell = tableCells.get(2);
      cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
      paragraph = cell.getParagraphArray(0);
      paragraph.setAlignment(ParagraphAlignment.CENTER);
      run = paragraph.createRun();
      run.setFontSize(10);
      run.setFontFamily("Microsoft Yahei");
      run.setText(item);
      
    }
    
  }
}
